<?php
declare(strict_types=1);

namespace App\Middleware;

use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Contract\ResponseInterface as HttpResponse;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Hyperf\Utils\Context;
use App\Service\Code\Normal;
use App\Service\HttpRequest\Http;
use App\Model\PssModel\Business;

class RequestVerifyMiddleware implements MiddlewareInterface
{
    /**
     * @var ContainerInterface
     */
    protected $container;

    /**
     * @var RequestInterface
     */
    protected $request;

    /**
     * @var HttpResponse
     */
    protected $response;

    public function __construct(ContainerInterface $container, HttpResponse $response, RequestInterface $request)
    {
        $this->container = $container;
        $this->response = $response;
        $this->request = $request;
    }

    //中间介质处理
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        try {
            $res = $this->checkParam($this->request->all());
            if( $res['code'] != Normal::SUC ) {
                return $this->response->json($res);
            }
            
            // 将新的请求对象设置到上下文中
            $request = $request->withAttribute('data',$res['data'])->withAttribute('request_start_time',microtime(true));
            Context::set(ServerRequestInterface::class, $request);
            return $handler->handle($request);
        } catch ( \Throwable $th ) {
            return $this->response->json(Normal::returnCode(Normal::FAIL,"系统异常【{$th->getMessage()}】",[
                'errorLine' => $th->getLine(),
                'errorFile' => $th->getFile()
            ]));
        }
    }
    
    //验证签名
    protected function checkParam( $param = [] )
    {
        if( empty($param['appid']) ) {
            return Normal::returnCode(Normal::FAIL,'appid参数不能为空');
        }
        
        if( empty($param['sign']) ) {
            return Normal::returnCode(Normal::FAIL,'sign参数不能为空');
        }
        
        if( empty($param['requestMethod']) ) {
            return Normal::returnCode(Normal::FAIL,'requestMethod参数不能为空');
        }
        
        if( !isset($param['requestData']) ) {
            return Normal::returnCode(Normal::FAIL,'requestData参数不能为空');
        }
        
        $param['requestData'] = rawurlencode(rawurldecode($param['requestData']));
        
        //获取商户信息
        $merchantInfo = Business::instance()->getMerchantUserInfoByAppId($param['appid']);
        if( empty($merchantInfo) || empty($merchantInfo['appid']) || empty($merchantInfo['secret']) ) {
            return Normal::returnCode(Normal::FAIL,'获取商户信息appid失败');
        }
        
        //判断商户是否正常启用
        if( $merchantInfo['status'] == 1 ) {
            return Normal::returnCode(Normal::FAIL,'当前商户被禁用，无权限，请联系业务或者管理员开通');
        }
        
        //判断是否进行授权操作
        if( $merchantInfo['is_router_user'] != 1 && $merchantInfo['user_source'] == 2 && ($merchantInfo['has_template'] != 1 || empty($merchantInfo['template_price_tpl'])) ) {
            return Normal::returnCode(Normal::FAIL,'当前商户未进行授权商品操作，请联系业务或者管理员处理！');
        }
        
        //验证签名
        $checkSignStr = strtoupper(Http::getSign($param,$merchantInfo['secret']));
        if( $checkSignStr !== $param['sign'] ) {
            return Normal::returnCode(Normal::FAIL,'验证签名失败');
        }
        
        $param['requestData'] = json_decode(rawurldecode($param['requestData']),true);
        $param['requestMethod'] = ucfirst($param['requestMethod']);
        $param['binfo'] = $merchantInfo;
        return Normal::returnCode(Normal::SUC,'验证通过',[
            'param' => $param
        ]);
    }
}
